#include "list.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
// mylist datanode[2];

typedef struct list_node {
    struct list_head node; /*node 为链表名*/
    char*            data;
} mylist; /*包含内核链表的容器*/
/**
 * @description: 初始化链表
 * @param {list_head*} head 链表头
 * @return {*}
 */
void init_list(struct list_head* head)
{
    INIT_LIST_HEAD(head);
}
/**
 * @description: 向数据节点中插入数据
 * @param {mylist*} datanode 包含链表的数据节点
 * @param {char*} data  要插入的数据
 * @param {int} datalen 要插入的数据长度
 * @return {*} 0:成功 -1:失败
 */
int insertDataToNode(mylist* datanode, const char* data, int datalen)
{
    datanode->data = (char*)calloc(1, datalen + 1);
    if(!datanode->data) {
        printf("malloc failde\n");
        return -1;
    }
    memcpy(datanode->data, data, datalen);
}
/**
 * @description: 将节点添加进链表
 * @param {list_head*} head 链表头
 * @param {mylist*} datanode    数据节点
 * @return {*}
 */
void add_list(struct list_head* head, mylist* datanode)
{
    list_add_tail(&datanode->node, head);
}
/**
 * @description:
 * @param {list_head} *head
 * @return {*}
 */
void foreach_list(struct list_head* head)
{
    mylist *pos, *n;
    /*pos:记录位置,n:容器类型指针,head:链表头,node:链表名*/
    list_for_each_entry_safe(pos, n, head, node)
    {
        printf("%s\n", pos->data);
        // sleep(5);
    }
}
/**
 * @description:根据data销毁链表
 * @param {list_head} *head
 * @param {char} *data
 * @return {*}
 */
void delnode_list(struct list_head* head, char* data)
{
    int     len = strlen(data);
    mylist *pos, *n;
    list_for_each_entry_safe(pos, n, head, node)
    {
        if(0 == memcmp(pos->data, data, len)) {
            mylist* datanode = container_of(&pos->node, mylist, node);
            // printf("%p\n",datanode);
            free(datanode->data);
            datanode->data = NULL;
            list_del(&datanode->node);
            free(datanode);
            datanode = NULL;
            printf("free success\n");
        }
    }
}
/*销毁整条链表*/
void destroy_list(struct list_head* head)
{
    mylist *pos, *n;
    list_for_each_entry_safe(pos, n, head, node)
    {
        mylist* datanode = container_of(&pos->node, mylist, node);
        printf("%s\n", datanode->data);
        if(datanode->data) free(datanode->data);
        datanode->data = NULL;
        list_del(&datanode->node);
        free(datanode);
        datanode = NULL;
        printf("free success\n");
    }
}
/**
 * @description:
 * @param {list_head} *head
 * @param {char} *data
 * @return {*}
 */
void addNodeToList(struct list_head* head, const char* data)
{
    mylist* datanode = (mylist*)calloc(1, sizeof(mylist));
    // printf("%d %s\n",strlen(data),data);
    // printf("%p\n",datanode);
    insertDataToNode(datanode, data, strlen(data));
    add_list(head, datanode);
}
mylist* findDataFromList(struct list_head* head, char* data)
{
    int     len = strlen(data);
    mylist *pos, *n;
    list_for_each_entry_safe(pos, n, head, node)
    {
        if(0 == memcmp(pos->data, data, len)) {
            mylist* datanode = container_of(&pos->node, mylist, node);
            return pos;
        }
    }
    return NULL;
}
int main()
{
    struct list_head head;
    init_list(&head);
    // mylist datanode[2];
    // insertDataToNode(&datanode[0],"hello",5);
    // add_list(&head,&datanode[0]);
    // insertDataToNode(&datanode[1],"world",5);
    // add_list(&head,&datanode[1]);
    mylist* n      = NULL;
    char    buf1[] = "hello";
    char    buf2[] = "world";
    char    buf3[] = "world1";
    char    buf4[] = "world2";
    addNodeToList(&head, buf1);
    addNodeToList(&head, buf2);
    addNodeToList(&head, buf3);
    addNodeToList(&head, buf4);
    mylist* mynode  = findDataFromList(&head, buf1);
    mylist* mynode1 = findDataFromList(&head, "ni");
    // printf("%s\n",mynode->data);
    /*从当前节点的后一个节点开始遍历*/
    list_for_each_entry_safe_continue(mynode, n, &head, node)
    {
        printf("%s\n", mynode->data);
    }
    mynode1 = container_of(head.next, mylist, node); //获取头节点
    printf("%s\n", mynode1->data);
    mynode1 = container_of(head.prev, mylist, node); //获取尾节点
    printf("%s\n", mynode1->data);
    mynode1 = container_of(head.next, mylist, node); //获取头节点

    free(mynode1->data);
    mynode1->data = NULL;
    list_del(&mynode1->node);
    if(mynode1) {
        free(mynode1);
        mynode1 = NULL;
    }
    // if(NULL == mynode1) { printf("no this data\n"); }
    // foreach_list(&head);
    destroy_list(&head);
    // delnode_list(&head, buf1);
    // foreach_list(&head);
    // delnode_list(&head, buf2);
    // foreach_list(&head);
    return 0;
}